package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"regexp"
)

// 用于匹配 @include_once 和随机 CSS 文件名的正则表达式
const (
	maliciousPattern = `\.\w*\.(\\x63ss|css).*@include_once`
)

func scanDirectory(dir string) {
	// 编译正则表达式
	re, err := regexp.Compile(maliciousPattern)
	if err != nil {
		fmt.Println("正则表达式编译失败:", err)
		return
	}

	// 遍历目录
	err = filepath.WalkDir(dir, func(path string, info os.DirEntry, err error) error {
		if err != nil {
			fmt.Println("访问文件时出错:", err)
			return nil
		}

		if !info.IsDir() && filepath.Ext(path) == ".php" {
			// 打开文件进行读取
			file, err := os.Open(path)
			if err != nil {
				fmt.Println("打开文件时出错:", err)
				return nil
			}

			defer file.Close()
			lineNumber := 0
			// 逐行检查
			scanner := bufio.NewScanner(file)
			buf := make([]byte, 0, 64*1024)
			scanner.Buffer(buf, 1024*1024*10)
			for scanner.Scan() {
				line := scanner.Text()
				lineNumber++
				// 检查是否包含恶意代码模式
				if re.MatchString(line) {
					fmt.Printf("恶意代码文件: %s\n", path)
					break
				}
			}
			if err := scanner.Err(); err != nil {
				fmt.Println("扫描文件时出错:", err)
			}
		}

		return nil
	})

	if err != nil {
		fmt.Println("目录扫描失败:", err)
	}
}

func main() {
	// 解析命令行参数
	dir := flag.String("dir", ".", "要扫描的目录路径")
	flag.Parse()

	// 调用函数扫描指定目录
	scanDirectory(*dir)
}
